package com.xtsoft.platform.base.system.utils;


import com.alibaba.fastjson.JSONArray;
import com.xtsoft.core.utils.StringUtils;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * 版权 @Copyright: 2017 xintuo 项目名称：webos-base<br/>
 * 文件名称： TreeBuilder.java<br/>
 * 包名：com.xtsoft.base.web.rest.util 创建人：@author lgw
 * 创建时间：2017年5月3日/下午3:06:58<br/>
 * 修改时间：2017年5月3日<br/>
 * 修改备注：<br/>
 */
public class TreeBuilder<T> {

	List<Node> nodes = new ArrayList<Node>();
	private final Logger log = LoggerFactory.getLogger(TreeBuilder.class);


	/**
	 * <b>Description:构建树</b><br>
	 * 
	 * @param list        对象list集合
	 * @param arry        需要生成树所对应字段数组 {"id","父Id","显示值","对象主键Id","图标","方法",""}，
	 *                    前四个必须指向
	 * @param entityClass 实体类
	 * @return json
	 * @Note <b>Author:lgw</b> <br>
	 *       <b>Date:</b>2017年5月3日 下午3:07:20 <br>
	 *       <b>Version:</b> 1.0
	 */
	public String buildTree(List<T> list, String[] arry, Class<T> entityClass) {
		List<Node> nodesList = new ArrayList<Node>();
		Method[] methods = entityClass.getDeclaredMethods();
		for (T entity : list) {
			nodesList.add(changeNode(entity, arry, methods));
		}
		this.nodes = nodesList;
		String json = buildJSONTree();
		if (arry.length < 8) {
			json = json.replaceAll("\"checked\":false,", "");
		}
		return json;
	}

	/**
	 * 
	 * <b>Description 将实体类 转换node节点最新</b><br>
	 * 
	 * @param entity  实体类
	 * @param array   需要生成树所对应字段数组 {"id","父Id","显示值","对象主键Id","图标","方法","类型",""}，
	 *                前四个必须指向
	 * @param methods 类所包含方法
	 * @return node节点
	 * @Note <b>Author:lgw</b> <br>
	 *       <b>Date:</b>2017年5月3日 下午3:12:19 <br>
	 *       <b>Version:</b> 1.0
	 */
	public Node changeNode(T entity, String[] array, Method[] methods) {
		Node node = new Node();
		boolean flag = false;
		String fieldValue = null;
		for (int i = 0; i < array.length; i++) {
			if(StringUtils.isBlank(array[i]))
				continue;
			for (Method method : methods) {
				
				if (method.getName().startsWith("get") && method.getName().equals("get" + array[i].substring(0, 1).toUpperCase() + array[i].substring(1))) {
					try {
						if (null != method.invoke(entity)) {
							fieldValue = method.invoke(entity).toString();
						} else {
							fieldValue = null;
						}
						flag = true;
						break;
					} catch (Exception e) {
						log.debug(method.getName());
						
					} /*
						 * catch (IllegalAccessException e) { // TODO Auto-generated catch block
						 * 
						 * e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO
						 * Auto-generated catch block e.printStackTrace(); } catch
						 * (InvocationTargetException e) { // TODO Auto-generated catch block
						 * 
						 * e.printStackTrace(); }
						 */

				}
			}
			if (flag) {
				switch (i) {
				case 0:
					node.setId(fieldValue);
					break;
				case 1:
					node.setPid(fieldValue);
					break;
				case 2:
					node.setText(fieldValue);
					break;
				case 3:
					node.setResUniqueId(fieldValue);
					break;
				case 4:
					node.setIconCls(fieldValue);
					break;
				case 5:
					node.setViewType(fieldValue);
					break;
				case 6:
					node.setDataType(fieldValue);
					break;
				case 7:
					node.setChecked(Boolean.valueOf(fieldValue).booleanValue());
					break;

				default:
					break;
				}
			}
		}
		return node;
	}

	/**
	 * 构建JSON树形结构 1
	 * 
	 * @return
	 */
	public String buildJSONTree() {
		List<Node> nodeTree = buildTree();
		JSONArray jsonArray = JSONArray.parseArray(nodeTree.toString());
		return jsonArray.toString();
	}

	/**
	 * 判断是否是叶子节点
	 * 
	 * @return
	 */
	public void isLeaf(Node node) {
		node.setLeaf(true);
	}

	/**
	 * 构建树形结构 2
	 * 
	 * @return
	 */
	public List<Node> buildTree() {
		List<Node> treeNodes = new ArrayList<Node>();
		List<Node> rootNodes = getRootNodes();
		for (Node rootNode : rootNodes) {
			buildChildNodes(rootNode);
			treeNodes.add(rootNode);
		}
		return treeNodes;
	}

	/**
	 * 递归子节点 5
	 * 
	 * @param node
	 */
	public void buildChildNodes(Node node) {
		List<Node> children = getChildNodes(node);
		if (!children.isEmpty()) {
			for (Node child : children) {
				buildChildNodes(child);
			}
			node.setChildren(children);
			node.setLeaf(false);
		} else {
			node.setLeaf(true);
		}
	}

	/**
	 * 获取父节点下所有的子节点
	 * 
	 * @param pnode

	 * @return
	 */
	public List<Node> getChildNodes(Node pnode) {
		List<Node> childNodes = new ArrayList<Node>();
		for (Node n : nodes) {
			if (pnode.getId().equals(n.getPid())) {
				childNodes.add(n);
			}
		}
		return childNodes;
	}

	/**
	 * 判断是否为根节点 4
	 * 
	 * @param node

	 * @return
	 */
	public boolean rootNode(Node node) {
		boolean isRootNode = true;
		for (Node n : nodes) {
			if (node.getPid().equals(n.getId())) {
//				isLeaf(node);
				isRootNode = false;
				break;
			}
		}
		return isRootNode;
	}

	/**
	 * 获取集合中所有的根节点 3
	 * 

	 * @return
	 */
	public List<Node> getRootNodes() {
		List<Node> rootNodes = new ArrayList<Node>();
		for (Node n : nodes) {
			if (rootNode(n)) {
				rootNodes.add(n);
			}
		}
		return rootNodes;
	}
	
	public String buildTreeForTopicFill(List<T> list, String[] arry, Class<T> entityClass) {
		List<Node> nodesList = new ArrayList<Node>();
		Method[] methods = entityClass.getDeclaredMethods();
		for (T entity : list) {
			nodesList.add(changeNodeForTopicFill(entity, arry, methods));
		}
		this.nodes = nodesList;
		String json = buildJSONTree();
//		if (arry.length < 8) {
//			json = json.replaceAll("\"checked\":false,", "");
//		}
		return json;
	}

	/**
	 * <p> 树形填报  </p>  
	 * @param entity
	 * @param array
	 * @param methods
	 * @return
	 * @return Node
	 * @throws  
	 * @author tuyingchao 
	 * @date 2019年12月24日 
	 * @time 下午2:26:58
	 */
	public Node changeNodeForTopicFill(T entity, String[] array, Method[] methods) {
		Node node = new Node();
		boolean flag = false;
		String fieldValue = null;
		for (int i = 0; i < array.length; i++) {
			if(StringUtils.isBlank(array[i]))
				continue;
			for (Method method : methods) {
				if (method.getName().startsWith("get") && method.getName().equals("get" + array[i].substring(0, 1).toUpperCase() + array[i].substring(1))) {
					try {
						if (null != method.invoke(entity)) {
							fieldValue = method.invoke(entity).toString();
						} else {
							fieldValue = null;
						}
						flag = true;
						break;
					} catch (Exception e) {
						log.debug(method.getName());
					}
				}
			}
			if (flag) {
				switch (i) {
				case 0:
					node.setId(fieldValue);
					break;
				case 1:
					node.setPid(fieldValue);
					break;
				case 2:
					node.setText(fieldValue);
					break;
				case 3:
					node.setResUniqueId(fieldValue);
					break;
				case 4:
					node.setAnswer(fieldValue);
					break;
				case 5:
					node.setIndexValue(fieldValue);
					break;
				case 6:
					node.setUrl(fieldValue);
					break;
				case 7:
					node.setFilePath(fieldValue);
					break;
				default:
					break;
				}
			}
		}
		return node;
	}
	
	public static class Node {

		private String id;
		private String pid;
		private String text;
		private String iconCls;
		private String viewType;
		private String resUniqueId;
		private String dataType;
		private Boolean checked;
		private Boolean leaf;
		private List<Node> children;
		private String answer;
		private String indexValue;
		private String url;
		private String filePath;
		public Node() {
		}
		
		public Node(String id, String pid, String text, String resUniqueId, String iconCls, String viewType,
				String dataType,String answer,String indexValue,String url,String filePath) {
			super();
			this.id = id;
			this.pid = pid;
			this.text = text;
			this.iconCls = iconCls;
			this.answer = answer;
			this.indexValue = indexValue;
			this.url = url;
			this.filePath = filePath;
			this.resUniqueId = resUniqueId;
			this.viewType = viewType;
			this.dataType = dataType;
		}
		
		public Node(String id, String pid, String text, String resUniqueId, String iconCls, String viewType,
				String dataType) {
			super();
			this.id = id;
			this.pid = pid;
			this.text = text;
			this.iconCls = iconCls;
			this.resUniqueId = resUniqueId;
			this.viewType = viewType;
			this.dataType = dataType;
		}

		/**
		 * config(id,pid,text,iconCls,viewType)
		 * 
		 * @return
		 */

		public String getId() {
			return id;
		}

		public Boolean getLeaf() {
			return leaf;
		}

		public void setLeaf(Boolean leaf) {
			this.leaf = leaf;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getDataType() {
			return dataType;
		}

		public void setDataType(String dataType) {
			this.dataType = dataType;
		}

		public String getPid() {
			return pid;
		}

		public void setPid(String pid) {
			this.pid = pid;
		}

		public String getText() {
			return text;
		}

		public void setText(String text) {
			this.text = text;
		}

		public String getIconCls() {
			return iconCls;
		}

		public void setIconCls(String iconCls) {
			this.iconCls = iconCls;
		}

		public String getViewType() {
			return viewType;
		}

		public void setViewType(String viewType) {
			this.viewType = viewType;
		}

		public List<Node> getChildren() {
			return children;
		}

		public void setChildren(List<Node> children) {
			this.children = children;
		}

		public String getResUniqueId() {
			return resUniqueId;
		}

		public void setResUniqueId(String resUniqueId) {
			this.resUniqueId = resUniqueId;
		}

		public Boolean getChecked() {
			return checked;
		}

		public void setChecked(Boolean checked) {

			this.checked = checked;
		}
		public String getAnswer() {
			return answer;
		}

		public void setAnswer(String answer) {
			this.answer = answer;
		}

		public String getIndexValue() {
			return indexValue;
		}

		public void setIndexValue(String indexValue) {
			this.indexValue = indexValue;
		}

		public String getUrl() {
			return url;
		}

		public void setUrl(String url) {
			this.url = url;
		}

		public String getFilePath() {
			return filePath;
		}

		public void setFilePath(String filePath) {
			this.filePath = filePath;
		}
	}
}